import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    private DatagramSocket socket = null;

    /**
     *
     * @param port 表示端口号 范围0~65535
     */
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    /**
     * 用来启动服务器
     */
    public void start() throws IOException {
        System.out.println("服务器启动!!!");
        // 服务器一般都是持续运行的(7*24)
        while (true) {
            // 1. 读取请求 如果服务器不知道客户端啥时候发来请求,就会等待
            // 如果请求来了,receive就会返回
            // 参数 DatagramPacket 是一个输出型参数. socket中读取到的参数就会设置到这个参数的对象中.
            // DatagramPacket 构造时,需要指定缓冲区
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            // 将 requestPacket 中的内容取出,作为一个字符串
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            // 2. 根据请求计算响应
            String response = process(request);
            // 3. 把响应写回到客户端. (需要构造 DatagramPacket)
            // 注意设置长度时,必须是字节
            // 此时也需要设置发送的地址
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            // 4. 加上日志打印
            String log = String.format("[%s:%d] req: %s; resp: %s",
                    requestPacket.getAddress().toString(),
                    requestPacket.getPort(),
                    request,response);
            System.out.println(log);
        }
    }

    // 计算响应 -> 回想服务器,直接返回客户端发的请求即可.
    private String process(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}
